define([
	'jquery',
	'underscore',
	'backbone',
	// add to window
], function($, _, Backbone) {
	window.$ = $; // jquery;

	var isDebug = true;
	var debug = isDebug ? console.log.bind(console) : function() {};

	var blueInk = {};
	blueInk.debug = debug;
	blueInk.history = []; // path,qs,view
	blueInk.container = $('#container'); // only one container

	// supported qs 
	// reuse=1 reuse previous layer of this path, default=1
	// refresh=1 refresh page, default=1
	// remsamepath=1 remove same path
	var optDef = {
		reuse: 1,
		refresh: 1
	}

	// router
	var Router = blueInk.Router = Backbone.Router.extend({
		routes: {
			'*path(?*qs)': 'any'
		},
		any: function(path, qs) {
			debug('route to => ' + path + "?" + qs);
			path = __normalPath(path);
			if (!path) return;

			// check if go back
			var opt = __parseQueryString(qs);
			if (typeof opt.reuse === 'undefined') {
				opt.reuse = optDef.reuse;
			}
			if (typeof opt.refresh === 'undefined') {
				opt.refresh = optDef.refresh;
			}
			var hisLen = blueInk.history.length;
			if (hisLen >= 2 && blueInk.history[hisLen - 2].path === path) {
				blueInk.goBack(opt); // goback
			} else {
				blueInk.loadModule(path, opt);
			}
		}
	});

	// normalize path
	function __normalPath(path) {
		var input = path;
		if (!path) return path;

		if (path.startsWith('#')) {
			path = path.substring(1);
		}

		// end with / , a/b = a/b/
		if (path && path.endsWith('/')) {
			path = path.substring(0, path.length - 1);
		}
		if (!path.endsWith('.js')) {
			path = path + '/start.js'; // default js file
		}

		// blueInk.debug('__normalPath,in=%s,out=%s', input, path);
		return path;
	}

	// ?a=b&c=d => {a:b,c:d}
	function __parseQueryString(qs) {
		var obj = {};
		if (!qs) return obj;

		var qs = qs.replace(/^\s?\?/, ""); //去掉?
		var arr = qs.split('&');
		arr.forEach(function(item) {
			var pair = item.split('=');
			obj[pair[0]] = pair[1];
		});
		return obj;
	}

	// remove the top view
	blueInk.goBack = function(opt) {
		debug('goBack,opt=', opt);
		var topView = blueInk.history.pop();
		topView.view.remove(); // remove permenently

		var hisLen = blueInk.history.length;
		if (opt && opt.refresh) {
			blueInk.history[hisLen - 1].view.refresh();
		} else {
			blueInk.history[hisLen - 1].view.show();
		}
	};

	// add a new layer in view TODO
	blueInk.newViewLayer = function(el) {
		blueInk.container.append(el);
	};

	blueInk.hasHistory = function(path) {
		return blueInk.history.some(function(item) {
			return item.path === path;
		});
	};

	blueInk.refreshTop = function(opt) {
		var hisLen = blueInk.history.length;
		var path = blueInk.history[hisLen - 1].path;
		blueInk.reuseMod(path, opt);
	};

	// remove top view, show the next
	blueInk.removeTop = function(opt) {

	};

	blueInk.addView = function(path, modView) {
		blueInk.container.append(modView.el);
		modView.show();
		blueInk.history.push({
			path: path,
			view: modView
		});

		// the old view 
		var hisLen = blueInk.history.length;
		if (hisLen >= 2) {
			blueInk.history[hisLen - 2].view.hide();
		}
	};

	blueInk.reuseMod = function(path, opt) {
		var hisLen = blueInk.history.length;
		var index = 0;
		for (; index < hisLen; index++) {
			if (blueInk.history[index].path === path)
				break;
		}
		if (index == hisLen) return false;

		// bring this mod to front
		// first remove view,then append
		var target = blueInk.history.splice(index, 1)[0];
		var modView = target.view;
		modView.remove({
			keepEvent: true
		});
		if (opt && opt.refresh) {
			debug('refresh');
			modView.refresh(function done() {
				blueInk.addView(path, modView);
			})
		} else {
			debug('show');
			modView.render(function done() {
				blueInk.addView(path, modView); // show
			});
		}
		return true;
	};

	// remove module
	blueInk.removeModule = function(path) {
		path = __normalPath(path);
		var hisLen = blueInk.history.length;
		var index = 0;
		for (; index < hisLen; index++) {
			if (blueInk.history[index].path === path)
				break;
		}
		if (index === hisLen) return false;

		var target = blueInk.history.splice(index, 1)[0];
		var modView = target && target.view;
		modView && modView.remove();
	};

	// load new module
	blueInk.loadModule = function(path, opt) {
		if (!!opt.reuse) {
			if (blueInk.hasHistory(path)) {
				debug('require reuse ok');
				blueInk.reuseMod(path, opt);
				return;
			} else {
				debug('require reuse but not found ', path);
			}
		}

		require([path], function(ModView) {
			// the new view
			// debug('send opt=', opt);
			var modView = new ModView(opt);
			modView.render(function done() {
				blueInk.addView(path, modView); // show
			});
		});
	};

	// 启动
	var router = new Router();
	Backbone.history.start();

	// add to window
	this.blueInk = blueInk;
	return blueInk;
});